package writer;

import com.intellij.codeInsight.actions.ReformatCodeProcessor;
import com.intellij.openapi.command.WriteCommandAction;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.*;
import com.intellij.psi.codeStyle.JavaCodeStyleManager;
import model.Element;

import java.awt.*;
import java.util.List;

/**
 * Created by jiao on 16/4/24.
 */
public class AutoWriter extends WriteCommandAction.Simple {

    private static final String MODIFIER = "private";
    private static final String BLANK = " ";
    private static final String SEMICOLON = ";";
    private static final String PREFIX = "android.widget.";
    private final PsiClass mCls;
    private final List<Element> mElements;
    private final PsiElementFactory mFactory;
    private final Project mProject;
    private final PsiFile mFile;
    private final PsiElement mCurrentElement;

    public AutoWriter(PsiClass cls, PsiFile file, PsiElement currentElement, String commandName, List<Element> elements) {
        super(cls.getProject(), commandName);
        this.mFile = file;
        this.mProject = cls.getProject();
        this.mCurrentElement = currentElement;
        this.mElements = elements;
        this.mCls = cls;
        this.mFactory = JavaPsiFacade.getElementFactory(mProject);
    }

    @Override
    protected void run() throws Throwable {
        if (mElements == null || mElements.size() == 0) {
            return;
        }

        try {
            generateFields();
            generateFindViewMethod();
            generateCallFindView();
        } catch (Exception e) {
            e.printStackTrace();
            T(e.getMessage());
        }

        JavaCodeStyleManager manager = JavaCodeStyleManager.getInstance(mProject);
        manager.optimizeImports(mFile);
        manager.shortenClassReferences(mCls);
        new ReformatCodeProcessor(mProject, mCls.getContainingFile(), null, false).runWithoutProgress();
    }

    private void generateCallFindView() {
        PsiStatement call = mFactory.createStatementFromText("findView();", mCls);
        PsiElement element = mCurrentElement;
        while (!(element instanceof PsiMethod)) {
            element = element.getParent();
        }
        ((PsiMethod) element).getBody().add(call);
    }

    private void generateFindViewMethod() {
        PsiMethod findView = mFactory.createMethod("findView", PsiType.VOID);
        findView.getModifierList().setModifierProperty("private", true);

        for (Element e : mElements) {
            if (e == null) {
                continue;
            }
            String name;
            if (!StringUtil.isEmpty(e.nameFull)) {
                name = e.nameFull;
            } else if ("View".equals(e.name)) {
                name = "android.view.View";
            } else {
                name = PREFIX + e.name;
            }

            String statement = String.format("%s = (%s)findViewById(R.id.%s);", e.fieldName, name, e.id);
            PsiStatement line = mFactory.createStatementFromText(statement, mCls);
            findView.getBody().add(line);
        }
        mCls.add(findView);
    }

    private void generateFields() {
        for (Element e : mElements) {
            if (e == null) {
                continue;
            }
            String name;
            if (!StringUtil.isEmpty(e.nameFull)) {
                name = e.nameFull;
            } else if ("View".equals(e.name)) {
                name = "android.view.View";
            } else {
                name = PREFIX + e.name;
            }

            StringBuilder sb = new StringBuilder();
            sb.append(MODIFIER)
                    .append(BLANK)
                    .append(name)
                    .append(BLANK)
                    .append(e.fieldName)
                    .append(SEMICOLON);
            mCls.add(mFactory.createFieldFromText(sb.toString(), mCls));
        }
    }

    public void T(Object s) {
        Messages.showInfoMessage(String.valueOf(s), "蘑菇信息");
    }

}
